package com.appkubes.fintech.admin.application.risk.data.boole.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.appkubes.fintech.admin.application.risk.data.boole.dao.RiskBooleDao;
import com.appkubes.fintech.admin.application.risk.data.boole.service.BooleRiskService;
import com.appkubes.fintech.admin.application.risk.data.boole.utils.AES;
import com.appkubes.fintech.admin.application.risk.data.boole.utils.BooleApiEncryptionUtil;
import com.appkubes.fintech.admin.application.risk.data.boole.utils.RSA;
import com.appkubes.fintech.admin.application.user.dao.AfuAfruadDao;
import com.appkubes.fintech.admin.application.user.dao.UserBankCardDao;
import com.appkubes.fintech.admin.application.user.dao.UserBaseInfoDao;
import com.appkubes.fintech.admin.application.user.dao.UserDao;
import com.appkubes.fintech.admin.application.user.entity.dto.AfuAfruadDto;
import com.appkubes.fintech.common.exption.BusinessException;
import com.appkubes.fintech.core.po.*;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Author: wuzhijian
 * @Date: 2019/12/25
 * @Description:
 */
@Service
@Slf4j
public class BooleRiskServiceImpl implements BooleRiskService {

    @Resource
    private UserDao userDao;

    @Resource
    private UserBaseInfoDao userBaseInfoDao;

    @Resource
    private UserBankCardDao userBankCardDao;

    @Resource
    private RiskBooleDao riskBooleDao;

    @Resource
    private AfuAfruadDao afuAfruadDao;

    /**
     * 接口请求地址
     */
    @Value("${boole.data.url}")
    private String url;

    @Value("${boole.data.institutionId}")
    private String institutionId;

    @Value("${boole.data.aesKey}")
    private String aesKey;


    @Value("${boole.data.rsaPrivateKey}")
    private String rsaPrivateKey;

    @Override
    public com.appkubes.fintech.common.response.Response checkPhone(String userKey) {
        try {
            FintechUser fintechUser = userDao.selectByPrimaryKey(userKey);
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            if (fintechUser == null || baseInfo == null) {
                return com.appkubes.fintech.common.response.Response.fail("无该用户");
            }

            Map<String, Object> customData = new TreeMap<>();
            customData.put("name", baseInfo.getRealName());
            customData.put("phone", baseInfo.getPhone());
            customData.put("ident_number", baseInfo.getIdentityNum());
            customData.put("service", "network_operator_triple_elements");
            customData.put("mode", "mode_triple_elements");

            String responseJson = getResponse(customData, userKey);
            JSONObject resJson = JSONObject.parseObject(responseJson);
            if (resJson.getString("resp_code").equals("SW0000")) {
                JSONObject respData = resJson.getJSONObject("resp_data");
                if (respData.getString("result_code").equals("02")) {
                    fintechUser.setCertificate3(1);
                    return com.appkubes.fintech.common.response.Response.success("认证成功");
                } else {
                    fintechUser.setCertificate3(2);
                }
                userDao.updateByPrimaryKey(fintechUser);
            }
            return com.appkubes.fintech.common.response.Response.fail("认证不通过：" + resJson.getString("resp_code"));
        } catch (Exception e) {
            return com.appkubes.fintech.common.response.Response.fail("运营商认证出错：e=" + e.getMessage());
        }
    }


    @Override
    public com.appkubes.fintech.common.response.Response checkBank(String userKey) {
        try {
            FintechUser fintechUser = userDao.selectByPrimaryKey(userKey);
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            FintechUserBankCard userBankCard = userBankCardDao.selectByPrimaryKey(userKey);
            if (fintechUser == null || baseInfo == null || userBankCard == null) {
                return com.appkubes.fintech.common.response.Response.fail("无该用户");
            }

            Map<String, Object> customData = new TreeMap<>();
            customData.put("name", baseInfo.getRealName());
            customData.put("bank_card", userBankCard.getBankCardNumber());
            customData.put("ident_number", baseInfo.getIdentityNum());
            customData.put("phone", baseInfo.getPhone());
            customData.put("service", "bankcard_four_elements_alpha_service");
            customData.put("mode", "bankcard_four_elements_alpha_mode");

            String responseJson = getResponse(customData, userKey);
            JSONObject resJson = JSONObject.parseObject(responseJson);
            if (resJson.getString("resp_code").equals("SW0000")) {
                JSONObject respData = resJson.getJSONObject("resp_data");
                if (respData.getString("result_code").equals("02")) {
                    fintechUser.setCertificate4(1);
                    fintechUser.setIsOperatorGet(1);
                    fintechUser.setIsAllCertificate(1);
                    return com.appkubes.fintech.common.response.Response.success("银行卡四要素认证成功");
                } else {
                    fintechUser.setCertificate4(2);
                }
                userDao.updateByPrimaryKey(fintechUser);
            }
            return com.appkubes.fintech.common.response.Response.fail("认证不通过：" + resJson.getString("resp_code"));
        } catch (Exception e) {
            return com.appkubes.fintech.common.response.Response.fail("银行卡四要素：e=" + e.getMessage());
        }
    }

    @Override
    public com.appkubes.fintech.common.response.Response getPreRisk(String userKey) {
        try {
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            FintechUserBankCard userBankCard = userBankCardDao.selectByPrimaryKey(userKey);
            if (baseInfo == null || userBankCard == null) {
                return com.appkubes.fintech.common.response.Response.fail("无该用户");
            }

            String responseJson = getPreRiskStr(userKey);
            JSONObject resJson = JSONObject.parseObject(responseJson);
            if (resJson.getString("resp_code").equals("SW0000")) {
                JSONObject respData = resJson.getJSONObject("resp_data");
                return com.appkubes.fintech.common.response.Response.success(respData);
            }
            return com.appkubes.fintech.common.response.Response.fail(resJson.getString("resp_msg"));
        } catch (Exception e) {
            return com.appkubes.fintech.common.response.Response.fail("获取前置租赁风险错误：e=" + e.getMessage());
        }
    }

    @Override
    public com.appkubes.fintech.common.response.Response getAfuRisk(String userKey) {
        try {
            FintechDataAfuFruadExample fintechDataAfuFruadExample = new FintechDataAfuFruadExample();
            fintechDataAfuFruadExample.createCriteria().andUserKeyEqualTo(userKey);
            List<FintechDataAfuFruad> list = afuAfruadDao.selectByExampleWithBLOBs(fintechDataAfuFruadExample);
            if (!list.isEmpty() && list.size() > 0) {
                String result = list.get(0).getData();
                AfuAfruadDto t = new Gson().fromJson(result, AfuAfruadDto.class);
                t.getRiskResult().forEach(
                        it -> {
                            if ("CREDITEASE".equals(it.getDataType())) {
                                it.setDataType("网贷");
                            } else if ("COURT_LITIGATION".equals(it.getDataType())) {
                                it.setDataType("法院诉讼");
                            } else if ("OTHER".equals(it.getDataType())) {
                                it.setDataType("其他");
                            } else if ("NETWORK".equals(it.getDataType())) {
                                it.setDataType("网络");
                            }

                            if ("ID_NO".equals(it.getRiskItemType())) {
                                it.setRiskItemType("本人身份证号");
                            } else if ("CONTACT_ID_NO".equals(it.getRiskItemType())) {
                                it.setRiskItemType("联系人身份证号");
                            } else if ("MOBILE".equals(it.getRiskItemType())) {
                                it.setRiskItemType("本人手机号码");
                            } else if ("BANK_NO".equals(it.getRiskItemType())) {
                                it.setRiskItemType("银行卡号");
                            }

                            if ("ARREARS".equals(it.getRiskDetail())) {
                                it.setRiskDetail("长期拖欠");
                            } else if ("COURT_EXECUTED".equals(it.getRiskDetail())) {
                                it.setRiskDetail("法院-被执行");
                            } else if ("RECENT_EXIST_MULTI_APPLY_RISK".equals(it.getRiskDetail())) {
                                it.setRiskDetail("近期存在多头申请风险");
                            } else if ("MODEL_EVALUATION_LOW_QUALIFICATION".equals(it.getRiskDetail())) {
                                it.setRiskDetail("模型评估低资质");
                            } else if ("SMALL_BUSINESS_ARREARS".equals(it.getRiskDetail())) {
                                it.setRiskDetail("小额业务拖欠");
                            } else if ("FIRST_OVER_SUSPECTED_FRAUD".equals(it.getRiskDetail())) {
                                it.setRiskDetail("首逾 M3");
                            } else if ("DIFFICULTIES_OBTAIN_SMALL_BUSINESS".equals(it.getRiskDetail())) {
                                it.setRiskDetail("小额业务获批困难");
                            } else if ("FAKE_INFO".equals(it.getRiskDetail())) {
                                it.setRiskDetail("申请信息虚假");
                            } else if ("FAKE_DATA".equals(it.getRiskDetail())) {
                                it.setRiskDetail("资料虚假");
                            } else if ("PSEUDO".equals(it.getRiskDetail())) {
                                it.setRiskDetail("伪冒");
                            } else if ("LOSS_PAYMENT".equals(it.getRiskDetail())) {
                                it.setRiskDetail("丧失还款能力");
                            } else if ("RISK_USEAGE".equals(it.getRiskDetail())) {
                                it.setRiskDetail("用途风险");
                            } else if ("AGENCY".equals(it.getRiskDetail())) {
                                it.setRiskDetail("同行中介");
                            } else if ("COURT_PROMISE_BREAKING".equals(it.getRiskDetail())) {
                                it.setRiskDetail("法院-失信");
                            }
                        }
                );
                return com.appkubes.fintech.common.response.Response.success(t);
            } else {
                return com.appkubes.fintech.common.response.Response.fail("暂无数据");
            }
        } catch (Exception e) {
            return com.appkubes.fintech.common.response.Response.fail("获取阿福报告错误：e=" + e.getMessage());
        }
    }

    @Override
    public String getPreRiskStr(String userKey) {
        try {
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            FintechUserBankCard userBankCard = userBankCardDao.selectByPrimaryKey(userKey);
            if (baseInfo == null || userBankCard == null) {
                return "";
            }

            Map<String, Object> customData = new TreeMap<>();
            customData.put("name", baseInfo.getRealName());
            customData.put("ident_number", baseInfo.getIdentityNum());
            customData.put("phone", baseInfo.getPhone());
            customData.put("service", "rental_prerisk_report_service");
            customData.put("mode", "mode_rental_prerisk_report");

            String responseJson = getResponse(customData, userKey);
            return responseJson;
        } catch (Exception e) {
            return "";
        }
    }


    @Override
    public com.appkubes.fintech.common.response.Response getProphetReport(String userKey) {
        try {
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            FintechUserBankCard userBankCard = userBankCardDao.selectByPrimaryKey(userKey);
            if (baseInfo == null || userBankCard == null) {
                return com.appkubes.fintech.common.response.Response.fail("无该用户");
            }

            String responseJson = getProphetReportStr(userKey);
            JSONObject resJson = JSONObject.parseObject(responseJson);
            if (resJson.getString("resp_code").equals("SW0000")) {
                JSONObject respData = resJson.getJSONObject("resp_data");
                return com.appkubes.fintech.common.response.Response.success(respData);
            }
            return com.appkubes.fintech.common.response.Response.fail(resJson.getString("resp_msg"));
        } catch (Exception e) {
            return com.appkubes.fintech.common.response.Response.fail("获取预言家报告错误：e=" + e.getMessage());
        }
    }

    @Override
    public String getProphetReportStr(String userKey) {
        try {
            FintechUserBaseInfo baseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
            FintechUserBankCard userBankCard = userBankCardDao.selectByPrimaryKey(userKey);
            if (baseInfo == null || userBankCard == null) {
                return "";
            }

            Map<String, Object> customData = new TreeMap<>();
            customData.put("name", baseInfo.getRealName());
            customData.put("ident_number", baseInfo.getIdentityNum());
            customData.put("phone", baseInfo.getPhone());
            customData.put("service", "prophet_report_service");
            customData.put("mode", "mode_prophet_report");

            String responseJson = getResponse(customData, userKey);
            return responseJson;
        } catch (Exception e) {
            return "";
        }
    }

    private String getResponse(Map<String, Object> customData, String userKey) throws Exception {
        String strResult = "";
        String inputStr = JSONObject.toJSONString(customData);
        String md5Key = DigestUtils.md5Hex(inputStr);

        FintechRiskBooleWithBLOBs riskBoole = (FintechRiskBooleWithBLOBs) riskBooleDao.selectByPrimaryKey(md5Key);
        if (riskBoole != null) {
            strResult = riskBoole.getOutput();
            riskBoole.setUpdateTime(new Date());
            riskBooleDao.updateByPrimaryKey(riskBoole);
        } else {
            // RSA 加密
            String js = RSA.getSignContent(new JSONObject(customData));
            String signVal = RSA.sign(js, rsaPrivateKey);

            // AES 加密
            String bizDataRaw = JSONObject.toJSON(customData).toString();
            String bizDataEncoded = AES.encrypt(bizDataRaw, aesKey);

            Map<String, Object> data = new HashMap<>();
            String signEncoded = URLEncoder.encode(signVal);
            String bizDataEncoded2 = URLEncoder.encode(bizDataEncoded);
            data.put("institution_id", institutionId);
            data.put("charset", "UTF-8");
            data.put("sign_type", "RSA2");
            data.put("sign", signEncoded);
            data.put("timestamp", "");
            data.put("version", "V1.0.1");
            data.put("biz_data", bizDataEncoded2);

            Response response = BooleApiEncryptionUtil.postWithRetry(url, data);
            ResponseBody body = response.body();
            if (body == null) {
                throw new BusinessException("远程没有返回体！");
            }
            strResult = body.string();

            riskBoole = new FintechRiskBooleWithBLOBs();
            riskBoole.setMd5key(md5Key);
            riskBoole.setInput(inputStr);
            riskBoole.setOutput(strResult);
            riskBoole.setCreateTime(new Date());
            riskBoole.setUserKey(userKey);
            riskBooleDao.insert(riskBoole);
        }

        return strResult;
    }
}
